<?php
include "dataHandlerClass.php";
include "elementHandlerClass.php";
include "structHandlerClass.php";
include "relationHandlerClass.php";
/*
 * CONFIGURATION CONSTANTS
*/

define("SEPARATOR",'/');
define("ID_SEPARATOR",'-');

define("ROOT_NAME",'/SISTEMA');
define("DATA_TABLENAME","data");
define("STRUCT_TABLENAME","structure");
define("ELEMENTS_TABLENAME","elements");
define("INTERNAL_NODES_TYPE_NAME","node");
define("ELEMENT_NODES_TYPE_NAME","element");
define("VALUE_TYPES","integer,string,date,real,boolean,");
//se aplica a nombres de nodos de estructura
define("NODES_NAME_REGEX",'/^[a-zd_-]{1,28}[0-9]{0,10}$/i');
//se aplica a nombres de elementos simples
define("ELEMENTS_NAME_REGEX",'/^[a-zd_]{1,28}[0-9]{0,10}$/i');


/**
 * This class contains the functions to manage the data model based in Nested Set Model.
 * This file contains the constants to config the model.
 * @author CEPAL.
 */
class Model {
    public $parametros;
    public $gestorDatos;
    public $gestorElementos;
    public $gestorEstructura;
    public $gestorRelaciones;

   /**
    * This function loads the configuration parameters from the constants defined before.
    * @param boolean $debug OPTIONAL parameter to show debug messages.
    */
    function __construct($debug=false){
        $this->parametros=array();
        $this->parametros['id_char']=ID_SEPARATOR;
        $this->parametros['root_name']=ROOT_NAME;
        $this->parametros['internal_nodes_type_name']=INTERNAL_NODES_TYPE_NAME;
        $this->parametros['element_nodes_type_name']=ELEMENT_NODES_TYPE_NAME;
        $this->parametros['value_types']=VALUE_TYPES;
        $this->parametros['nodes_name_regex']=NODES_NAME_REGEX;
        $this->parametros['elements_name_regex']=ELEMENTS_NAME_REGEX;
        $this->parametros['separator']=SEPARATOR;

        $this->gestorEstructura= new StructHandler(STRUCT_TABLENAME, $this->parametros, $debug);
        $this->gestorElementos=new ElementHandler(ELEMENTS_TABLENAME,$this->parametros,$debug);
        $this->gestorDatos=new DataHandler(DATA_TABLENAME, $this->parametros,$debug);
        $this->gestorRelaciones=new RelationHandler(ELEMENTS_TABLENAME, $this->parametros, $debug);
    }


    /**
     * This function return a value of an attribute especified in $path
     * If the attribute doesn't exist returns NULL
     * @param string $path contains the path to the attribute.
     * @param boolean $debug OPTIONAL parameter to show debug messages.
     * @return mixed
     */
    public function getValue($path,$debug=false){
        return $this->gestorDatos->getValue($path,$this->gestorElementos,$this->gestorEstructura,$this->gestorRelaciones,$debug);
    }


    /**
     * This function sets the value of an attribute.
     * If the attribute doesn't exist returns false.
     * @param string $path contains the path to the attribute.
     * @param mixed $value contains the value to set.
     * @param boolean $debug OPTIONAL parameter to show debug messages.
     * @return boolean
     */
    public function setValue($path,$value,$debug=false){
        return $this->gestorDatos->setValue($path,$value,$this->gestorElementos,$this->gestorEstructura,$this->gestorRelaciones,$debug);
    }


    /**
     * This function deletes a value of an attribute.
     * If the attribute doesn't exist returns false.
     * @param string $path contains the path to the attribute.
     * @param boolean $debug OPTIONAL parameter to show debug messages.
     * @return boolean
     */
    public function deleteValue($path,$debug=false){
        return $this->gestorDatos->deleteValue($path,$this->gestorElementos,$this->gestorEstructura,$debug);
    }


    /**
     * This function inserts a new element.
     * @param string $type contains an element type.
     * @param string $name contains the name of the element to insert.
     * @param boolean $debug OPTIONAL parameter to show debug messages.
     * @return boolean
     */
    public function insertElement($type,$name,$debug=false){
        return $this->gestorElementos->insert($type, $name,$this->gestorEstructura,$debug);
    }


    /**
     * This function deletes an element and all its data.
     * @param string $name contains the name of the element to delete.
     * @param boolean $debug OPTIONAL parameter to show debug messages.
     * @return boolean
     */
    public function deleteElement($name,$debug=false){
        $this->gestorDatos->deleteValuesById($this->gestorElementos->getId($name,$debug),$debug);
        return $this->gestorElementos->delete($name,$debug);
    }


    public function createRelation($name,$debug=false){
        return $this->gestorRelaciones->createRelation($name, $this->gestorEstructura,$this->gestorElementos, $debug);
    }

    public function deleteRelation($name,$debug=false){
        return $this->gestorRelaciones->delete($name, $debug);
    }

    public function getRelation($name,$debug=false){
        return $this->gestorRelaciones->getRelation($name);
    }

    /**
     * This function returns the ID of an element specified by $name.
     * @param string $name contains the name of the element.
     * @param boolean $debug OPTIONAL parameter to show debug messages.
     * @return integer
     */
    public function getId($name,$debug=false){
        return $this->gestorElementos->getId($name,$debug);
    }

    public function existsRelation($name){
        return $this->gestorRelaciones->exists($name);
    }


    /**
     * This function will be deleted from this class.
     * @TODO replace this function with XML load functions.
     * @deprecated
     */
    public function addChild($nombreNodo,$tipo, $nombrePadre, $nombreHermano,$debug=false){
        if ($nombreHermano==""){
            $np=$this->parametros['root_name'].$nombrePadre;
            $nh="";
        }else{
            $np="";
            $nh=$this->parametros['root_name'].$nombreHermano;
        }

        return $this->gestorEstructura->addChild($nombreNodo, $tipo, $np, $nh,$debug);
    }


    /**
     * This function initializes an empty structure.
     * @param boolean $debug OPTIONAL parameter to show debug messages.
     * @return boolean
     */
    public function initializeStruct($debug=false){
        return $this->gestorEstructura->addChild(substr($this->parametros['root_name'],1),INTERNAL_NODES_TYPE_NAME,"","",$debug);
    }




}
?>
